Dart 泛型
Lawrence 2023/6/2
# Dart 泛型
泛型是在函数、类、接口中指定 宽泛数据类型 的语法。
通常,在尖括号中,使用一个字母来代表类型,类如 E T S K 和 V 等。
返回类型 函数名<输入类型>(参数类型 参数) {
函数体
}
1
2
3
2
3
使用泛型可以帮我们减少重复的代码。我现在通过一个函数就可以替代多个需要明确数据类型的函数。
泛型的类型传递过程:
# 泛型函数
// String getData(String value) {
// return value;
// }
// int getData(int value) {
// return value;
// }
// 不指定数据类型的函数
// getData(value) {
// return value;
// }
T getData<T>(T value) {
return value;
}
// 只约定参数类型,不约定函数返回值的类型
// getData<T>(T value) {
// return value;
// }
void main() {
// print(getData(1));
// 调用泛型函数
print(getData<int>(20));
print(getData<String>('Hello'));
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# 泛型类
class CommonClass {
Set s = new Set<int>();
void add(int value) {
this.s.add(value);
}
void info() {
print(this.s);
}
}
// 泛型类
class GenericsClass<T> {
Set s = new Set<T>();
void add(T value) {
this.s.add(value);
}
void info() {
print(this.s);
}
}
void main() {
CommonClass c = new CommonClass();
c.add(1);
c.add(2);
c.info();
// 实例化泛型类
GenericsClass g = new GenericsClass<int>();
g.add(1);
g.add(2);
g.info();
GenericsClass g1 = new GenericsClass<String>();
g1.add('Hello');
g1.add('World');
g1.info();
// Set s = new Set();
// s.add(1);
// s.add('hello');
// print(s);
// Set s = new Set<int>();
// s.add(1);
// s.add('hello'); // 运行时报错
// s.add(3);
// print(s);
// 字面量形式的泛型
Set s = <int>{};
s.add(1);
// s.add('hello'); // 运行时报错
s.add(3);
print(s);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# 泛型接口
abstract class ObjectCache {
getByKey(String key);
void setByKey(String key, Object value);
}
abstract class StringCache {
getByKey(String key);
void setByKey(String key, String value);
}
// 泛型接口
abstract class Cache<T> {
getByKey(String key);
void setByKey(String key, T value);
}
// 文件缓存
class FileCache<T> implements Cache<T> {
getByKey(String key) {
return null;
}
void setByKey(String key, T value) {
print('文件缓存: key=${key} value=${value}');
}
}
// 内存缓存
class MemoryCache<T> implements Cache<T> {
getByKey(String key) {
return null;
}
void setByKey(String key, T value) {
print('内存缓存: key=${key} value=${value}');
}
}
void main() {
// 文件缓存 - 缓存字符串
// FileCache fc = new FileCache<String>();
// fc.setByKey('foo', 'bar');
// fc.setByKey('foo', 2); // 运行时报错
// 文件缓存 - 缓存 Map
FileCache fc = new FileCache<Map>();
fc.setByKey('index', {"name": "张三丰", "age": 129});
// 内存缓存 - 缓存字符串
// MemoryCache mc = new MemoryCache<String>();
// mc.setByKey('foo', 'bar');
// 内存缓存 - 缓存集合
MemoryCache mc = new MemoryCache<Set>();
mc.setByKey('home', {1, 2, 3});
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# 泛型类型限制
class SomeBaseClass {
// ...
}
class Foo<T extends SomeBaseClass> {
String toString() => "Instance of 'Foo<$T>'";
}
// 子类
class Extender extends SomeBaseClass {
// ...
}
class AnotherClass {
// ...
}
void main() {
var someBaseClass = Foo<SomeBaseClass>();
print(someBaseClass); // Instance of 'Foo<SomeBaseClass>'
var extenderFoo = Foo<Extender>();
print(extenderFoo); // Instance of 'Foo<Extender>'
var foo = Foo();
print(foo); // Instance of 'Foo<SomeBaseClass>'
// var f = Foo<AnotherClass>(); // 类型不对
// print(f);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30